package cn.easyplatform.studio.web.controller;

import cn.easyplatform.entities.beans.project.ProjectBean;
import cn.easyplatform.lang.Strings;
import cn.easyplatform.studio.StudioApp;
import cn.easyplatform.studio.cmd.identity.*;
import cn.easyplatform.studio.context.Contexts;
import cn.easyplatform.studio.utils.WebUtils;
import cn.easyplatform.studio.vos.ProjectRoleVo;
import cn.easyplatform.studio.vos.RoleVo;
import cn.easyplatform.studio.web.editors.Editor;
import cn.easyplatform.studio.web.editors.EditorCallback;
import cn.easyplatform.studio.web.views.impl.AbstractView;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.metainfo.ComponentInfo;
import org.zkoss.zk.ui.util.Composer;
import org.zkoss.zk.ui.util.ComposerExt;
import org.zkoss.zkmax.zul.Cascader;
import org.zkoss.zul.*;
import org.zkoss.zul.theme.Themes;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;

public class ProductController implements Composer<Component>, ComposerExt<Component>, EventListener<Event> {
    private Component parentComponent;
    private Textbox searchTextbox;
    private Listbox productListbox;
    private Cascader cascaderDefault;

    List<ProjectRoleVo> projectRoleVoList;
    @Override
    public void onEvent(Event event) throws Exception {
        if ("product_hlayout_task".equals(event.getTarget().getId())) {
            if (StudioApp.getHelpConfig("project.task.url").length() > 0) {
                Executions.getCurrent().sendRedirect(StudioApp.getHelpConfig("project.task.url"), "_black");
            }
        } else if ("product_div_logout".equals(event.getTarget().getId())) {
            WebUtils.showConfirm(Labels.getLabel("user.logout"), new EventListener<Event>() {
                @Override
                public void onEvent(Event event) throws Exception {
                    if (event.getName().equals(Events.ON_OK)) {
                        //Clients.evalJavaScript("unloadChange(" + Boolean.FALSE + ")");
                        StudioApp.execute(parentComponent, new LogoutCmd(true));
                        Themes.setTheme(Executions.getCurrent(), "atrovirens_c");
                        Executions.sendRedirect("");
                    }
                }
            });
        } else if ("product_hlayout_password".equals(event.getTarget().getId())) {
            Executions.createComponents("~./include/normal/password.zul", null, null);
        } else if ("product_button_apply".equals(event.getTarget().getId())) {
            final ProjectBean[] projectBeans = StudioApp.execute(new GetStudioAllProjectCmd());
            AbstractView.createProject(event.getTarget(), new EditorCallback<List<ProjectBean>>() {
                @Override
                public List<ProjectBean> getValue() {
                    return Arrays.asList(projectBeans);
                }

                @Override
                public void setValue(List<ProjectBean> value) {

                }

                @Override
                public String getTitle() {
                    return Labels.getLabel("product.apply");
                }

                @Override
                public Page getPage() {
                    return parentComponent.getPage();
                }

                @Override
                public Editor getEditor() {
                    return null;
                }
            }, Contexts.getUser().getUserId()).doOverlapped();
        } else if (searchTextbox.equals(event.getTarget())) {
            search();
        } else if (cascaderDefault.equals(event.getTarget())) {
            if (cascaderDefault.getSelectedItems().isEmpty() == false) {
                LinkedHashSet<DefaultTreeNode> defaultTreeNodes = (LinkedHashSet<DefaultTreeNode>) cascaderDefault.getSelectedItems();
                Object[] nodes = defaultTreeNodes.toArray();
                String projectId = (String)((DefaultTreeNode) nodes[0]).getData();
                String roleId = (String)((DefaultTreeNode) nodes[1]).getData();
                if (Strings.isBlank(projectId) == false && Strings.isBlank(roleId) == false) {
                    Boolean isSuccess = StudioApp.execute(new UpdateDefaultProjectCmd(Contexts.getUser().getUserId(),
                            projectId+","+roleId));
                    if (isSuccess) {
                        WebUtils.showSuccess(Labels.getLabel("product.default.project.success"));
                    }
                }
            }
        }
    }

    @Override
    public void doAfterCompose(Component component) throws Exception {
        parentComponent = component;
        component.query("#product_hlayout_task").addEventListener(Events.ON_CLICK, this);
        component.query("#product_div_logout").addEventListener(Events.ON_CLICK, this);
        ((Label)component.query("#product_label_name")).setValue(Contexts.getUser().getUserId());
        ((Label)component.query("#product_label_userName")).setValue(Contexts.getUser().getName());
        component.query("#product_hlayout_password").addEventListener(Events.ON_CLICK, this);
        component.query("#product_button_apply").addEventListener(Events.ON_CLICK, this);
        searchTextbox = (Textbox) component.query("#product_textbox_search");//product_textbox_search
        searchTextbox.addEventListener(Events.ON_OK, this);
        productListbox = (Listbox) component.query("#product_listbox_product");
        cascaderDefault = (Cascader) component.query("#product_cascader_default");
        cascaderDefault.addEventListener(Events.ON_SELECT, this);
        projectRoleVoList = Contexts.getUser().getRoleVoList();
        setValue();
        setList(projectRoleVoList);

        Component parentC = parentComponent.getParent().getParent();
        if (parentC instanceof Center) {
            component.getFellow("product_div_meContent").setVisible(false);
            component.getFellow("product_div_name").setVisible(false);
            component.getFellow("product_div_close").setVisible(false);
        }
    }

    @Override
    public ComponentInfo doBeforeCompose(Page page, Component component, ComponentInfo componentInfo) throws Exception {
        return componentInfo;
    }

    @Override
    public void doBeforeComposeChildren(Component component) throws Exception {

    }

    @Override
    public boolean doCatch(Throwable throwable) throws Exception {
        return false;
    }

    @Override
    public void doFinally() throws Exception {

    }

    private void setList(List<ProjectRoleVo> list) {
        productListbox.getItems().clear();
        if (list != null) {
            for (ProjectRoleVo roleVo : list) {
                //列表
                Listitem row = new Listitem();
                row.setValue(roleVo.getProjectId());
                row.appendChild(new Listcell(roleVo.getProjectId()));
                row.appendChild(new Listcell(roleVo.getProjectName()));
                row.appendChild(new Listcell(roleVo.getProjectDesp()));
                row.appendChild(new Listcell(roleVo.getRoleIDs()));
                Listcell listcell = new Listcell();
                A linkA = new A(Labels.getLabel("product.link"));
                linkA.setStyle("text-decoration:underline;");
                new ProjectRoleCell(linkA, roleVo);
                listcell.appendChild(linkA);
                row.appendChild(listcell);
                row.setParent(productListbox);
            }
        }
    }

    private void setValue() {
        List<DefaultTreeNode> firstNodeList = new ArrayList<>();
        if (projectRoleVoList != null) {
            for (ProjectRoleVo roleVo : projectRoleVoList) {
                List<DefaultTreeNode> secondNodeList = new ArrayList<>();
                if (Strings.isBlank(roleVo.getRoleIDs()) == false) {
                    String[] roles = roleVo.getRoleIDs().split(",");
                    for (String roleId : roles) {
                        secondNodeList.add(new DefaultTreeNode(roleId));
                    }
                }
                DefaultTreeNode firstNode = new DefaultTreeNode(roleVo.getProjectId(), secondNodeList);
                firstNodeList.add(firstNode);
            }
        }
        DefaultTreeNode treeNode = new DefaultTreeNode("ROOT", firstNodeList);
        DefaultTreeModel defaultTreeModel = new DefaultTreeModel(treeNode);
        cascaderDefault.setModel(defaultTreeModel);
        //设置
        String project = Contexts.getUser().getDefaultProject();
        int pIndex = 0;
        int rIndex = 0;
        boolean isSet = false;
        if (Strings.isBlank(project) == false && project.split(",").length == 2) {
            String defaultProjectId = project.split(",")[0];
            String defaultRoleId = project.split(",")[1];
            for (int i = 0; i < projectRoleVoList.size(); i++) {
                ProjectRoleVo roleVo = projectRoleVoList.get(i);
                if (roleVo.getProjectId().equals(defaultProjectId)) {
                    pIndex = i;
                    if (Strings.isBlank(roleVo.getRoleIDs()) == false) {
                        String[] roles = roleVo.getRoleIDs().split(",");
                        for (int index = 0; index < roles.length; index++) {
                            if (roles[index].equals(defaultRoleId)) {
                                rIndex = index;
                                isSet = true;
                                break;
                            }
                        }
                    }
                }
            }
        }
        defaultTreeModel.addSelectionPath(new int[]{pIndex, rIndex});
        if (isSet == false) {
            Events.postEvent(new Event(Events.ON_SELECT, cascaderDefault));
        }
    }

    private void search() {
        List<ProjectRoleVo> searchVos = new ArrayList<>();
        String searchString = searchTextbox.getValue().trim();
        if (Strings.isBlank(searchString))
            setList(projectRoleVoList);
        else {
            for (ProjectRoleVo projectRoleVo : projectRoleVoList) {
                if (projectRoleVo.getProjectId().contains(searchString) || projectRoleVo.getProjectName().contains(searchString)) {
                    searchVos.add(projectRoleVo);
                    continue;
                }
            }
            setList(searchVos);
        }
    }

    private class ProjectRoleCell implements EventListener<Event> {
        private A linkA;
        private ProjectRoleVo roleVo;

        public ProjectRoleCell(A linkA, ProjectRoleVo roleVo) {
            this.linkA = linkA;
            this.roleVo = roleVo;
            this.linkA.addEventListener(Events.ON_CLICK, this);
        }

        @Override
        public void onEvent(final Event event) throws Exception {
            if (linkA.equals(event.getTarget())) {
                //roleVo;
                final List<RoleVo> list = StudioApp.execute(new GetStudioRolesCmd(roleVo.getProjectId()));
                AbstractView.createLinkView(event.getTarget(), new EditorCallback<List<RoleVo>>() {
                    @Override
                    public List<RoleVo> getValue() {
                        return list;
                    }

                    @Override
                    public void setValue(List<RoleVo> value) {

                    }

                    @Override
                    public String getTitle() {
                        return Labels.getLabel("product.link");
                    }

                    @Override
                    public Page getPage() {
                        return event.getTarget().getPage();
                    }

                    @Override
                    public Editor getEditor() {
                        return null;
                    }
                }, roleVo.getProjectId(), Contexts.getUser().getUserId()).doOverlapped();
            }
        }
    }
}
